/*****************************************************************************/
/* Name: launch.c                                                            */
/* Description: Code skeleton for the launch progam.  This program creates   */
/*               multiple processes from command lines read from a user      */
/*               specified file.                                             */
/* Revision: 2_1_11                                                          */
/* Author: Scott J. Schneider                                                */
/*****************************************************************************/
/* Preprocessor directives */
#include	<windows.h>  // header file with Win32 API
#include	<stdio.h>
#include	<string.h>


/* Macro definitions */
#define	MAX_LINE_LEN	100  // maximum line length read from file


/* Functions */
/*****************************************************************************/
/* Name: main()                                                              */
/* Description: Main loop of execution, where the command line arguments are */
/*               parsed and the associated file is read to create processes  */
/*****************************************************************************/
int 
main(int argc, char *argv[]) 
{
/* Local variables */
    FILE *fid;  // file handle
    char fileLine[MAX_LINE_LEN];  // string to hold a line from the file
	char cmdLine[MAX_LINE_LEN];  // string to hold the command line

/* CreateProcess parameter variables */
    LPSECURITY_ATTRIBUTES processSA = NULL;  // Default
    LPSECURITY_ATTRIBUTES threadSA = NULL;  // Default
    BOOL shareRights = TRUE;  // Inherit handles
    DWORD creationMask = CREATE_NEW_CONSOLE;  // Window per process
    LPVOID environment = NULL;  // Same as calling Environment
    LPTSTR curDir = NULL;  // Default
    STARTUPINFO startInfo;  // Default
    PROCESS_INFORMATION procInfo;  // Result
/*************************************/

/* Parse the command line; argv[1] should be the filename */
    if( argc != 2 )  // expect 2 string elements in argv[]
    {		       //  else print correct usage
		printf("Usage:  launch <launch_set_filename>\n");
        exit(0);    
    }
/* Create processes according to the profile in argv[1] */
    if( (fid = fopen(argv[1], "r")) == NULL )  // open the file for reading
	{
		printf("Error openning file: %s", argv[1]);
		exit(0);
	}
    while( fgets(fileLine, MAX_LINE_LEN, fid) != NULL ) // read new lines until 
    {                                                  //  EOF reached
        sscanf(fileLine, "%s", cmdLine); // extract command line from file line

/* Define the necessary startInfo structure elements here */
/*  1) startInfo represents the set of parameters to use to start a process. */
/*  2) An instance must be defined in the calling program, and its address   */
/*     must be passed as a parameter in CreateProcess                        */
/*  3) CreateProcess does not know the length of the structure, therefore    */
/*     the size field must be initialized                                    */
/*  4) Use ZeroMemory() to allocate memory for the startInfo structure       */
         ZeroMemory(&startInfo, sizeof(startInfo)); 
		 startInfo.cb = sizeof(startInfo);
        
        if(!CreateProcess(
                NULL,        // File name of executable
                (LPWSTR)cmdLine,        // Command line
                processSA,        // Process inherited security
                threadSA,        // Thread inherited security
				shareRights,        // Rights propagation
                creationMask,        // Various creation flags
                environment,        // Environment variables
                curDir,        // Child's current directory
                &startInfo,        // Pointer to startupInfo
                &procInfo         // Pointer to procInfo
                )
            )
        {            
            fprintf(stderr, "CreateProcess failed on error %d\n", 
                    GetLastError());
            ExitProcess(0);
        }
    }    
/* Clean up, then terminate */
    // determining when all of the process have finished is difficult, 
    //  therefore each process should be started in its own console wiondow 
    //  or detached and then left to terminate on its own -> 
    //  Parent process launches the process and termines

    return 0;
}
